package com.hooview.api.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.hooview.api.dao.DailyCountMapper;
import com.hooview.api.dao.ProfitRecordMapper;
import com.hooview.api.dao.SignMapper;
import com.hooview.api.dao.UserMapper;
import com.hooview.api.entity.DailyCount;
import com.hooview.api.entity.ProfitRecord;
import com.hooview.api.entity.Sign;
import com.hooview.api.entity.User;
import com.hooview.api.service.ProfitRecordService;
import com.hooview.contants.Constants;
import com.hooview.utils.DateUtils;
import com.hooview.utils.SnowflakeIdWorker;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestBody;

import java.util.Calendar;
import java.util.Date;
import java.util.List;
@Service("profitService")
public class ProfitRecordServiceImpl implements ProfitRecordService {
    @Autowired
    private ProfitRecordMapper profitRecordMapper;
    @Autowired
    private SnowflakeIdWorker snowflakeIdWorker;
    @Autowired
    private DailyCountMapper dailyCountMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private SignMapper signMapper;

    @Override
    public List<ProfitRecord> queryByUser(String uid,Integer pageNum,Integer pageSize) {
        PageHelper.startPage(pageNum, pageSize,true);
        PageHelper.orderBy("create_time desc");
        Page<ProfitRecord> page = profitRecordMapper.selectByUser(uid);
        List<ProfitRecord> records = page.getResult();
        if(pageNum > page.getPages())
            return null;
        return records;
    }

    @Override
    public Float profitToday(String uid) {
        Calendar instance = Calendar.getInstance();
        instance.set(Calendar.HOUR_OF_DAY,0);
        instance.set(Calendar.MINUTE,0);
        instance.set(Calendar.SECOND,0);
        Date startTime = instance.getTime();
        instance.set(Calendar.HOUR_OF_DAY,23);
        instance.set(Calendar.MINUTE,59);
        instance.set(Calendar.SECOND,59);
        Date endTime = instance.getTime();
        return profitRecordMapper.profitToday(uid,startTime,endTime);
    }

    @Override
    public Double profitSum(String uid) {
        return profitRecordMapper.sumProfitByuser(uid);
    }

    @Override
    @Transactional(readOnly = false)
    public void save(@RequestBody ProfitRecord profitRecord) {
        if(StringUtils.isBlank(profitRecord.getId())) profitRecord.setId(String.valueOf(snowflakeIdWorker.nextId()));
        profitRecordMapper.insertSelective(profitRecord);
    }

    @Override
    public void update(ProfitRecord profitRecord) {

    }

    @Override
    public void delete(String id) {

    }

    @Override
    public Integer countByUser(String uid) {
        return profitRecordMapper.countByUser(uid);
    }

    @Override
    public ProfitRecord findByUserAndNewsId(String uid, Integer newsId) {
        return profitRecordMapper.findByUserAndNewsId(uid,newsId);
    }

    @Override
    @Transactional(readOnly = false)
    public Double getProfit(String uid, String type, Integer newsId) {
        DailyCount dailyCount = dailyCountMapper.selectByDate(new java.sql.Date(System.currentTimeMillis()),uid);
        if(dailyCount == null){
            dailyCount = new DailyCount();
            dailyCount.setUserId(uid);
            dailyCountMapper.insert(dailyCount);
        }
        dailyCount = dailyCountMapper.selectByDate(new java.sql.Date(System.currentTimeMillis()),uid);

        switch (type){
            case Constants.PROFIT_READ:
                return addReadProfit(uid,dailyCount,newsId);
            case Constants.PROFIT_SHARE_NEWS:
                return addShareNewsProfit(uid,dailyCount,newsId);
            case Constants.PROFIT_SHARE_ARTICLE:
                return addShareArticleProfit(uid,dailyCount,newsId);
            case Constants.PROFIT_SIGN:
                return addSignProfit(uid,dailyCount);
            case Constants.PROFIT_SUPPORT:
                return addSuppOrBoycProfit(uid,dailyCount,newsId,Constants.NEWS_SUPPORT);
            case Constants.PROFIT_BOYCOTT:
                return addSuppOrBoycProfit(uid,dailyCount,newsId,Constants.NEWS_BOYCOTT);
        }
        return null;
    }

    //利好利空收益
    @Transactional(readOnly = false)
    public Double addSuppOrBoycProfit(String uid, DailyCount dailyCount, Integer newsId, String type) {
        Integer suppBoycAmount = dailyCount.getSuppBoycAmount();
        dailyCount.setSuppBoycAmount(suppBoycAmount+1);
        dailyCountMapper.updateByPrimaryKeySelective(dailyCount);

        if(Constants.NEWS_SUPPORT.equals(type))
            type = Constants.PROFIT_SUPPORT;
        else
            type = Constants.PROFIT_BOYCOTT;
        switch (dailyCount.getSuppBoycAmount()){
            case 1:
                addProfit(uid,Constants.SUPP_BOYC_PROFIT_1,type,newsId);
                return Constants.SUPP_BOYC_PROFIT_1;
            case 2:
                addProfit(uid,Constants.SUPP_BOYC_PROFIT_2,type,newsId);
                return Constants.SUPP_BOYC_PROFIT_2;
            case 3:
                addProfit(uid,Constants.SUPP_BOYC_PROFIT_3,type,newsId);
                return Constants.SUPP_BOYC_PROFIT_3;
            case 4:
            case 5:
            case 6:
            case 7:
            case 8:
            case 9:
                addProfit(uid,Constants.SUPP_BOYC_PROFIT_4_9,type,newsId);
                return Constants.SUPP_BOYC_PROFIT_4_9;
        }
        return null;
    }

    @Override
    public ProfitRecord findByUserAndNewsIdAndType(String uid, Integer newsId, String type) {
        return profitRecordMapper.findByUserAndNewsIdAndType(uid,newsId,type);
    }

    @Override
    public Float todayToalProfits() {
        String time = DateUtils.formatDate(new Date());
        return profitRecordMapper.todayToalProfits(time);
    }

    //签到收益
    @Transactional(readOnly = false)
    public Double addSignProfit(String uid, DailyCount dailyCount) {
        dailyCount.setSign(dailyCount.getSign()+1);
        dailyCountMapper.updateByPrimaryKeySelective(dailyCount);

        Sign sign = signMapper.queryHead1ByUser(uid);
        switch (sign.getSignTimes()){
            case 1:
                addProfit(uid,Constants.SIGN_1,Constants.PROFIT_SIGN,null);
                break;
            case 2:
                addProfit(uid,Constants.SIGN_2,Constants.PROFIT_SIGN,null);
                break;
            case 3:
                addProfit(uid,Constants.SIGN_3,Constants.PROFIT_SIGN,null);
                break;
            case 4:
                addProfit(uid,Constants.SIGN_4,Constants.PROFIT_SIGN,null);
                break;
            case 5:
                addProfit(uid,Constants.SIGN_5,Constants.PROFIT_SIGN,null);
                break;
            case 6:
                addProfit(uid,Constants.SIGN_6,Constants.PROFIT_SIGN,null);
                break;
            case 7:
                addProfit(uid,Constants.SIGN_7,Constants.PROFIT_SIGN,null);
                break;
        }
        return null;
    }

    //分享文章收益
    @Transactional(readOnly = false)
    public Double addShareArticleProfit(String uid, DailyCount dailyCount,Integer newsId) {
        Integer shareArticleAmount = dailyCount.getShareArticleAmount();
        dailyCount.setShareArticleAmount(shareArticleAmount+1);
        dailyCountMapper.updateByPrimaryKeySelective(dailyCount);

        Double result = null;
        switch (dailyCount.getShareArticleAmount()) {
            case 1:
                addProfit(uid,Constants.SHARE_PROFIT_1,Constants.PROFIT_SHARE_ARTICLE,newsId);
                result = Constants.SHARE_PROFIT_1;
                break;
            case 2:
                addProfit(uid,Constants.SHARE_PROFIT_2,Constants.PROFIT_SHARE_ARTICLE,newsId);
                result = Constants.SHARE_PROFIT_2;
                break;
            case 3:
                addProfit(uid,Constants.SHARE_PROFIT_3,Constants.PROFIT_SHARE_ARTICLE,newsId);
                result = Constants.SHARE_PROFIT_3;
                break;
            case 4:
                addProfit(uid,Constants.SHARE_PROFIT_4,Constants.PROFIT_SHARE_ARTICLE,newsId);
                result = Constants.SHARE_PROFIT_4;
                break;
            case 5:
                addProfit(uid,Constants.SHARE_PROFIT_5,Constants.PROFIT_SHARE_ARTICLE,newsId);
                result = Constants.SHARE_PROFIT_5;
        }
        return result;
    }

    //分享快讯收益
    @Transactional(readOnly = false)
    public Double addShareNewsProfit(String uid, DailyCount dailyCount,Integer newsId) {
        Integer shareNewsAmount = dailyCount.getShareNewsAmount();
        dailyCount.setShareNewsAmount(shareNewsAmount+1);
        dailyCountMapper.updateByPrimaryKeySelective(dailyCount);

        Double result = null;
        switch (dailyCount.getShareNewsAmount()) {
            case 1:
                addProfit(uid,Constants.SHARE_PROFIT_1,Constants.PROFIT_SHARE_NEWS,newsId);
                result = Constants.SHARE_PROFIT_1;
                break;
            case 2:
                addProfit(uid,Constants.SHARE_PROFIT_2,Constants.PROFIT_SHARE_NEWS,newsId);
                result = Constants.SHARE_PROFIT_2;
                break;
            case 3:
                addProfit(uid,Constants.SHARE_PROFIT_3,Constants.PROFIT_SHARE_NEWS,newsId);
                result = Constants.SHARE_PROFIT_3;
                break;
            case 4:
                addProfit(uid,Constants.SHARE_PROFIT_4,Constants.PROFIT_SHARE_NEWS,newsId);
                result = Constants.SHARE_PROFIT_4;
                break;
            case 5:
                addProfit(uid,Constants.SHARE_PROFIT_5,Constants.PROFIT_SHARE_NEWS,newsId);
                result = Constants.SHARE_PROFIT_5;
        }
        return result;
    }

    //阅读收益
    @Transactional(readOnly = false)
    public Double addReadProfit(String uid, DailyCount dailyCount,Integer newsId) {
        Integer readAmount = dailyCount.getReadAmount();
        dailyCount.setReadAmount(readAmount+1);
        dailyCountMapper.updateByPrimaryKeySelective(dailyCount);

        Double result = null;
        switch (dailyCount.getReadAmount()) {
            case 1:
                addProfit(uid,Constants.READ_PROFIT_1,Constants.PROFIT_READ,newsId);
                result = Constants.READ_PROFIT_1;
                break;
            case 2:
                addProfit(uid,Constants.READ_PROFIT_2,Constants.PROFIT_READ,newsId);
                result = Constants.READ_PROFIT_2;
                break;
            case 3:
                addProfit(uid,Constants.READ_PROFIT_3,Constants.PROFIT_READ,newsId);
                result = Constants.READ_PROFIT_3;
                break;
            case 4:
            case 5:
            case 6:
            case 7:
            case 8:
                addProfit(uid,Constants.READ_PROFIT_4_5_6_7_8,Constants.PROFIT_READ,newsId);
                result = Constants.READ_PROFIT_4_5_6_7_8;
        }
        return result;
    }

    private void addProfit(String uid, Double num, String type, Integer newsId) {
        insert(uid, num, type, newsId,null);
        //是否有关联 用户
        User user = userMapper.selectByPrimaryKey(uid);
        User user_1 = null;
        User user_2 = null;
        if(StringUtils.isNotBlank(user.getReferee())) {
            user_1 = userMapper.selectByPrimaryKey(user.getReferee());
            if(StringUtils.isNotBlank(user_1.getReferee())){
                user_2 = userMapper.selectByPrimaryKey(user_1.getReferee());
            }
        }
        //上级收益
        if(user_1 != null){
            insert(user_1.getId(),num*Constants.REFERE_1,Constants.PROFIT_REFERE_1,newsId,uid);
        }
        //上上级收益
        if(user_2 != null){
            insert(user_2.getId(),num*Constants.REFERE_2, Constants.PROFIT_REFERE_2,newsId,user_1.getId());
        }

    }
    @Transactional(readOnly = false)
    public void insert(String uid, Double num, String type, Integer newsId,String refereId) {
        ProfitRecord profitRecord = new ProfitRecord();
        profitRecord.setUid(uid);
        profitRecord.setNum(num);
        profitRecord.setType(type);
        profitRecord.setId(String.valueOf(snowflakeIdWorker.nextId()));
        if(null != newsId)
            profitRecord.setNewsId(newsId);
        if(StringUtils.isNotBlank(refereId))
            profitRecord.setRefereId(refereId);
        profitRecordMapper.insert(profitRecord);
    }
}
